# -*- coding: utf-8 -*-
"""
@Time    : 2024/9/12 15:00 
@Author  : ZhangShenao 
@File    : 2.密码生成器.py 
@Desc    : 密码生成器
"""
import random


class PasswordGenerator:
    """密码生成器"""

    _upper_letters: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    """大写字母集合"""

    _lower_letters: str = "abcdefghijklmnopqrstuvwxyz"
    """小写字母集合"""

    _digits: str = "0123456789"
    """数字集合"""

    _special_chars: str = "~!@#$%^&*()_+-=[]{}|;:,.<>/?"
    """特殊字符集合"""

    _min_len: int = 8
    """密码最小长度"""

    _max_len: int = 20
    """密码最大长度"""

    def __init__(self):
        """构造函数"""
        pass

    def generate_password(self, length: int) -> str:
        """
        生成指定长度的密码
        规则:密码长度在[8,20]之间,至少包含1个大写字母、小写字母、数字和特殊字符,并且以字母开头
        :param length: 密码长度
        :return: 生成的密码
        """

        # 长度校验
        if length < self._min_len or length > self._max_len:
            raise ValueError(f"密码长度必须在{self._min_len}到{self._max_len}之间")

        code = ""

        # 生成密码开头
        # 必须以字母开头
        code += self._random_char(self._upper_letters + self._lower_letters)

        # 必须包含大写字母、小写字母、数字和特殊字符
        required = [self._random_char(self._upper_letters), self._random_char(self._lower_letters),
                    self._random_char(self._digits), self._random_char(self._special_chars)]

        # 打乱顺序
        random.shuffle(required)
        code += "".join(required)

        # 生成其余密码字符
        all_chars = self._upper_letters + self._lower_letters + self._digits + self._special_chars
        for i in range(0, length - 5):
            code += self._random_char(all_chars)

        return code

    @staticmethod
    def _random_char(chars: str):
        """从字符串中获取一个随机字符"""

        idx = random.randint(0, len(chars) - 1)
        return chars[idx]


if __name__ == '__main__':
    # 创建密码生成器对象
    pwd_gen = PasswordGenerator()

    # 生成密码
    pwd = pwd_gen.generate_password(12)
    print(f"生成的{len(pwd)}位密码: {pwd}")

    pwd = pwd_gen.generate_password(16)
    print(f"生成的{len(pwd)}位密码: {pwd}")
